#include <iostream>
#include <algorithm>
#include <list>
#include <typeinfo>
#include <vector>

#include <wx/cursor.h>
#include <wx/xml/xml.h>

#include "../include/BoneManager.h"
#include "../include/ProjectMain.h"
#include "../include/BoneState.h"


BEGIN_EVENT_TABLE(BoneManager, wxPanel)
    EVT_PAINT(BoneManager::paintEvent)
    EVT_MOTION(BoneManager::mouseMoved)
    EVT_ERASE_BACKGROUND(BoneManager::eraseBackground)

    EVT_LEFT_DOWN(BoneManager::mouseDown)
    EVT_LEFT_UP(BoneManager::mouseReleased)
    EVT_KEY_DOWN(BoneManager::onKeyDown)

END_EVENT_TABLE()

BoneManager::BoneManager(wxWindow* parent,
                    const wxSize& size,
                    Config* config,
                    BoneTreeCtrl* skeletonTree,
                    wxPanel* informationPanel,
                    wxWindowID id,
                    const wxString& name)
:wxPanel(parent, id, wxDefaultPosition, size, wxTAB_TRAVERSAL, name)
{
    this->projectFrame = dynamic_cast<ProjectFrame*>(parent);
    this->config = config;
    this->rootBone = NULL;
    this->selected = NULL;
    this->hovered = NULL;
    this->dragging = NULL;
    this->skeletonTree = skeletonTree;
    this->informationPanel = informationPanel;
    this->creatingBone = NULL;

    this->bonesStates = NULL;
    this->tmpBonesStates = NULL;

    this->skeletonTree->clear();
    skeletonTree->setBoneManager(this);
    animManager = new AnimationManager(this, config);
    projectFrame->enableAddBoneMode( true );

  /*  Bone* bone1;
    Bone* bone2;
    Bone* bone3;
    Bone* bone4;
    Bone* bone5;

    rootBone = new Bone( wxRealPoint(400, 100), wxRealPoint(400, 150), _("ROOTBOONE") );

    bone1 = new Bone(rootBone, 1 );
    bone1->setEnd( wxRealPoint(450, 195) );
    bone2 = new Bone(rootBone, 1, _("HAND2"));
    bone2->setEnd( wxRealPoint(350, 195) );
    bone3 = new Bone(rootBone, 1, _("BACK"));
    bone3->setEnd( wxRealPoint(400, 240) );
    bone4 = new Bone(bone3, 1, _("LEG1"));
    bone4->setEnd( wxRealPoint(350, 335) );
    bone5 = new Bone(bone3, 1, _("LEG2"));
    bone5->setEnd( wxRealPoint(450, 335) );


    bone2->setSprite( wxImage( _("triangle.png"), wxBITMAP_TYPE_PNG) );

    this->rebildSkeletonTree();
    this->saveSkeletonState();
*/

    //rootBone->rotate(2*M_PI + M_PI/2,Bone::BEGIN);


    this->SetFocus();
}

BoneManager::~BoneManager()
{
    //desrtoy animation manager
    if (animManager)
        delete animManager;

    if (!rootBone)
        return;

    //deleting bones
    std::list< Bone*> bones;
    bones.push_back(rootBone);

    std::list< Bone* >::iterator listIt, childenIt;
    for ( listIt = bones.begin(); listIt != bones.end(); ++listIt)
    {
        for ( childenIt = ( (*listIt)->getChildren() ).begin(); childenIt != ( (*listIt)->getChildren() ).end(); ++childenIt)
        {
            bones.push_back( (*childenIt) );
        }
        delete *listIt;
    }
}


AnimationManager* BoneManager::getAnimationManager() const
{
    return animManager;
}

Bone* BoneManager::setRootBone( Bone* bone )
{
    if( !rootBone )
        rootBone = bone;
    return rootBone;

}

void BoneManager::translateSkeletonByVector(wxPoint translation)
{
    if (!rootBone)
    {
        std::cerr << "There are no bones, in method BoneManager::translateSceleton(wxPoint)" << std::endl;
        return;
    }

    // moves the begining of rootBone
    rootBone->getBegin()->x += translation.x;
    rootBone->getBegin()->y += translation.y;


    // moves ends of all bones
    std::list< Bone*> bones;
    bones.push_back(rootBone);

    std::list< Bone* >::iterator listIt, childenIt;

    for ( listIt = bones.begin(); listIt != bones.end(); ++listIt)
    {
        for ( childenIt = ( (*listIt)->getChildren() ).begin(); childenIt != ( (*listIt)->getChildren() ).end(); ++childenIt)
        {
            bones.push_back( (*childenIt) );
        }

        (*listIt)->getEnd()->x += translation.x;
        (*listIt)->getEnd()->y += translation.y;
    }

}

Bone* BoneManager::findBoneById(unsigned boneId) const
{
    if (!rootBone)
    {
        std::cerr << "There are no bones" << std::endl;
        return NULL;
    }

    std::list< Bone*> bones;
    bones.push_back(rootBone);

    std::list< Bone* >::iterator listIt, childenIt;

    for ( listIt = bones.begin(); listIt != bones.end(); ++listIt)
    {
        for ( childenIt = ( (*listIt)->getChildren() ).begin(); childenIt != ( (*listIt)->getChildren() ).end(); ++childenIt)
        {
            bones.push_back( (*childenIt) );
        }

        // searchig for bone that will be selected
        if( (*listIt)->getBoneId() == boneId  )
        {
            return *listIt;
        }
    }

    // bone not found
    return NULL;
}

Bone* BoneManager::getSelectedBone() const
{
    return selected;
}

Bone* BoneManager::getRootBone() const
{
    return rootBone;
}

void BoneManager::PaintBackground(wxDC& dc)
{
    wxColour backgroundColour = GetBackgroundColour();
    if (!backgroundColour.Ok())
        backgroundColour =
            wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);

    dc.SetBackground(backgroundColour);
    dc.Clear();
}

void BoneManager::draw()
{
    wxBufferedPaintDC dc(this);
    PrepareDC(dc);
    PaintBackground(dc);

    PrepareDC(dc);

    if( rootBone )
    {
        std::list< Bone*> bones;
        bones.push_back(rootBone);

        std::list< Bone* >::iterator listIt, childenIt;

        for ( listIt = bones.begin(); listIt != bones.end(); ++listIt)
        {
            for ( childenIt = ( (*listIt)->getChildren() ).begin(); childenIt != ( (*listIt)->getChildren() ).end(); ++childenIt)
            {
                bones.push_back( (*childenIt) );
            }
            (*listIt)->draw(&dc);
        }
    }
}

void BoneManager::paintEvent(wxPaintEvent & evt)
{
    draw();
}

void BoneManager::mouseMoved(wxMouseEvent& evt)
{
    // if creating bones mode
    if( projectFrame->modeType() == 1 )
    {
        if( rootBone && rootBone->getChildren().empty() && creatingBone)
        {
            rootBone->setEnd( wxRealPoint( evt.GetPosition().x, evt.GetPosition().y ) );
            Refresh();
        }

        if( rootBone && !rootBone->getChildren().empty() && creatingBone)
        {
            selected->setEnd( wxRealPoint( evt.GetPosition().x, evt.GetPosition().y ) );
            Refresh();
        }
    }

    // if rotating and moving mode
    if( projectFrame->modeType() == 0 )
    {
        // dragging
        if( evt.Dragging() && dragging && hovered)
        {
        // moving sceleton by vector
        if (hovered == rootBone && rootBone->getSelectedJoint() == Bone::BEGIN)
        {
                translateSkeletonByVector( wxPoint(evt.GetPosition().x - rootBone->getBegin()->x, evt.GetPosition().y - rootBone->getBegin()->y) );
                Refresh();
                return;
        }

            double angle;
            angle = atan2( evt.GetPosition().y - hovered->getBegin()->y, evt.GetPosition().x - hovered->getBegin()->x );

            hovered->setAngle(angle);
            Refresh();
            return;
        }
    }

    // if not dragging then hovering
    if( rootBone )
    {

        std::list< Bone*> bones;
        bones.push_back(rootBone);

        std::list< Bone* >::iterator listIt, childenIt;

        for ( listIt = bones.begin(); listIt != bones.end(); ++listIt)
        {
            for ( childenIt = ( (*listIt)->getChildren() ).begin(); childenIt != ( (*listIt)->getChildren() ).end(); ++childenIt)
            {
                bones.push_back( (*childenIt) );
            }

            if(evt.m_x >= (*listIt)->getBegin()->x -2 &&
               evt.m_x <= (*listIt)->getBegin()->x +2 &&
               evt.m_y >= (*listIt)->getBegin()->y -2 &&
               evt.m_y <= (*listIt)->getBegin()->y +2)
            {
                wxCursor cursor(wxCURSOR_HAND);
                SetCursor( cursor );

                this->hoverBone(*listIt, Bone::BEGIN);
                hovered = *listIt;

                Refresh();
                return;
            }
            else if(evt.m_x >= (*listIt)->getEnd()->x -2 &&
                    evt.m_x <= (*listIt)->getEnd()->x +2 &&
                    evt.m_y >= (*listIt)->getEnd()->y -2 &&
                    evt.m_y <= (*listIt)->getEnd()->y +2)
            {
                wxCursor cursor(wxCURSOR_HAND);
                SetCursor( cursor );

                this->hoverBone(*listIt, Bone::END);
                hovered = *listIt;

                Refresh();
                return;
            }
        }

        if ( hovered )
        {
            hovered->hoverJoint(Bone::NON);
            hovered = NULL;
            wxCursor cursor(wxCURSOR_ARROW);
            SetCursor( cursor );
            Refresh();
        }
    }
}

void BoneManager::onKeyDown(wxKeyEvent& evt)
{
    if(evt.GetKeyCode() == 'S') // for save sceleton state
    {
        this->saveSkeletonState(false);
    }
    if(evt.GetKeyCode() == 'A') // for apply saved sceleton state
    {
        //this->applySkeletonState();
    }
    if(evt.GetKeyCode() == 'X') // for save skeleton to file
    {
        this->saveSkeletonToFile(_("samples/Ziom.bnf"), true);
    }
    if(evt.GetKeyCode() == 'L') // for load skeleton from file
    {
        this->loadSkeletonFromFile(_("samples/Ziom.bnf"), true);
    }
    if(evt.GetKeyCode() == '1')
    {
        animManager->addState(0, bonesStates);
        wxMessageBox(_("state added - 0"));
    }
    if(evt.GetKeyCode() == '8')
    {
        animManager->addState(8, bonesStates);
        wxMessageBox(_("state added - 8"));
    }
    if(evt.GetKeyCode() == '7')
    {
        applySkeletonState(2);
    }
    if(evt.GetKeyCode() == '9')
    {
        animManager->addState(2, bonesStates);
        wxMessageBox(_("state added - 2"));
    }
    if(evt.GetKeyCode() == '2')
    {
        applySkeletonState(1);
    }
    if(evt.GetKeyCode() == '4')
    {
        applySkeletonState(3);
    }

    if(evt.GetKeyCode() == '3')
    {
         wxString test;
           //test << _("orginalAnglr = ") << rootBone->angleOrginal;
           //test << _("rootbone loop = ") << rootBone->loopNumber << _(" rootbone angle=") << rootBone->deltaAngle;

            std::list< Bone*> bones;
            bones.push_back(rootBone);
           std::list< Bone* >::iterator listIt, childenIt;

            for ( listIt = bones.begin(); listIt != bones.end(); ++listIt)
            {
                for ( childenIt = ( (*listIt)->getChildren() ).begin(); childenIt != ( (*listIt)->getChildren() ).end(); ++childenIt)
                {
                    bones.push_back( (*childenIt) );
                }
                test << _("id = ") << (*listIt)->getBoneId() << (*listIt)->getName() <<  _("  loopsOrginal = ") << (*listIt)->getLoopsOrginal() << _(" loops = ") << (*listIt)->getLoops() << _(" amin = ") << (*listIt)->getAngleMin() << _(" amax= = ") << (*listIt)->getAngleMax() << _(" rel =") << (*listIt)->getLoopsRelative() << _("\n");
            }

           wxMessageBox( test );
    }

}

void BoneManager::selectBone(Bone* bone, Bone::JOINT joint)
{
    if (!bone)
    {
        std::cerr << "no bone specified, in method BoneManager::selectedBone(Bone*, Bone::JOINT)" << std::endl;
        return;
    }

    // unselect previous selection
     if (selected)
        selected->selectJoint(Bone::NON);

    selected = bone;
    selected->selectJoint(joint);
}

void BoneManager::hoverBone(Bone* bone, Bone::JOINT joint)
{
    if (!bone)
    {
        std::cerr << "no bone specified, in method BoneManager::hover jointBone(Bone*, Bone::JOINT)" << std::endl;
        return;
    }

    if (hovered)
        hovered->hoverJoint(Bone::NON);

    bone->hoverJoint(joint);
}

void BoneManager::eraseBackground(wxEraseEvent& evt)
{

}

/*void BoneManager::setBonesOrginalAngles()
{
    if (!rootBone)
    {
        std::cerr << "There is no bones in Method BoneManager::setBonesOrginalAngles" << std::endl;
        return;
    }
    std::list< Bone*> bones;
    bones.push_back(rootBone);

    std::list< Bone* >::iterator listIt, childenIt;

    for ( listIt = bones.begin(); listIt != bones.end(); ++listIt)
    {
        for ( childenIt = ( (*listIt)->getChildren() ).begin(); childenIt != ( (*listIt)->getChildren() ).end(); ++childenIt)
        {
            bones.push_back( (*childenIt) );
        }
        (*listIt)->setAngleOrginal();
    }
}*/

void BoneManager::applySkeletonState(unsigned frameNumber)
{
    std::vector<BoneState*>* states = NULL;

//    if ( animManager->hasState(frameNumber) )
//        states = bonesStates = animManager->calculateFrameState(frameNumber); //operate on states which are saved in anim manager
//    else
//    {   //operate on states, which are only to showing
//
//        //clear last tmp states if exist
//        if (tmpBonesStates)
//        {
//            std::vector<BoneState*>::iterator vecIt;
//            for(vecIt = tmpBonesStates->begin(); vecIt != tmpBonesStates->end(); vecIt++)
//                delete *vecIt;
//            delete tmpBonesStates;
//        }
//
//        states = tmpBonesStates = animManager->calculateFrameState(frameNumber);
//    }
    if ( animManager->hasState(frameNumber) )
        states = bonesStates = animManager->calculateFrameState(frameNumber); //operate on states which are saved in anim manager
    else
    {   //operate on states, which are only to showing

        //clear last tmp states if exist
        if (tmpBonesStates)
        {
            std::vector<BoneState*>::iterator vecIt;
            for(vecIt = tmpBonesStates->begin(); vecIt != tmpBonesStates->end(); vecIt++)
                delete *vecIt;
            delete tmpBonesStates;
        }

        states = bonesStates = tmpBonesStates = animManager->calculateFrameState(frameNumber);
    }

    if(!states) // There is no States to apply
        return;


    std::vector<BoneState*>::iterator vecIt;
    for(vecIt = states->begin(); vecIt != states->end(); vecIt++)
    {
        wxString test;
        test << _("before translation vecbone id=") << (*vecIt)->boneId << _(" vecloops =") << (*vecIt)->loops;
        //wxMessageBox( test );
    }

    if(!rootBone)
    {
        wxMessageBox( wxT("No root in applySeceletonState") );
        std::cerr << "There is no bone" << std::endl;
        return;
    }

    try
    {
        RootState * rootState = dynamic_cast<RootState*>(states->front());

        wxPoint translation(rootState->translation.x - rootBone->getBegin()->x, rootState->translation.y - rootBone->getBegin()->y );

        wxString test;
        test << _("dif.x = ") << translation.x << _("  dif.y = ") << translation.y;
        //wxMessageBox(test);

        translateSkeletonByVector(translation);
    }
    catch (std::bad_cast ex)
    {
        wxMessageBox( wxT("Dynamic cast fail in method BoneManager::applySceletonState()") );
        std::cerr << ex.what() << std::endl;
        return;
    }

    std::list< Bone*> bones;
    bones.push_back(rootBone);

    std::list< Bone* >::iterator listIt, childenIt;

    vecIt = states->begin();
    wxString test;
    for ( listIt = bones.begin(); listIt != bones.end(); ++listIt)
    {
        for ( childenIt = ( (*listIt)->getChildren() ).begin(); childenIt != ( (*listIt)->getChildren() ).end(); ++childenIt)
        {
            bones.push_back( (*childenIt) );
        }

        //vecIt = find_if(states.begin(), states.end(), **listIt);
        //if (vecIt == states.end() && )

       wxString test;
//       test << _("list boneid id=") << (*listIt)->getBoneId() << _(" vecbone id=") << (*vecIt)->boneId;
//       wxMessageBox( test );

        //vecIt = states.begin();
       (*listIt)->setBoneState( **vecIt );
       //test << _("id = ") << (*vecIt)->boneId << _(" loopBM = ") << (*vecIt)->loops << _("\n");

       ++vecIt;
        //break;
    }
    //wxMessageBox(test);
    //this->updateBoneInfo();
    Refresh();
}


std::vector<BoneState*>* BoneManager::saveSkeletonState(bool createNew)
{
    if(!rootBone)
    {
        std::cerr << "There is no bone, from method BoneManager::saveSceletonState()" << std::endl;
        wxMessageBox(_("no bones to save skeleton state"));
        return this->bonesStates;
    }
    //wxMessageBox(_("yo"));

//    if(bonesStates == tmpBonesStates)
//        wxMessageBox(_("bonesStaes = tmpBonestates in save"));
//    else
//        wxMessageBox(_("bonesStaes != tmpBonestates in save"));

    // create new States, from current skeleton position
    // previous states, are stored in animation manager
    if (createNew)
    {
        this->bonesStates = new std::vector<BoneState*>();
        //wxMessageBox(_("creating new states"));
    }
    else //updating current boneStates
    {
        //deleting old states
        //wxMessageBox(_("updating states"));
        std::vector<BoneState*>::iterator vecIt;
        for(vecIt = bonesStates->begin(); vecIt != bonesStates->end(); ++vecIt)
            delete *vecIt;
        bonesStates->clear();
    }

    std::list< Bone*> bones;
    std::list< Bone* >::iterator listIt, childenIt;

    bones.push_back(rootBone);

    // push into states vector Root bone state which contains, a translation vector
    RootState *rootState = new RootState (rootBone->getBoneState(), *(rootBone->getBegin()) );
    bonesStates->push_back(rootState);

    for ( listIt = bones.begin(); listIt != bones.end(); ++listIt)
    {
        for ( childenIt = ( (*listIt)->getChildren() ).begin(); childenIt != ( (*listIt)->getChildren() ).end(); ++childenIt)
            bones.push_back( (*childenIt) );

        // root bone is already added, before the loop
        if (listIt == bones.begin())
            continue;

        bonesStates->push_back( new BoneState ((*listIt)->getBoneState()) );
    }
    return this->bonesStates;


//    wxString test;
//    std::vector<BoneState*>::iterator vecIt;
//    for(vecIt = bonesStates->begin(); vecIt != bonesStates->end(); ++vecIt)
//    {
//       test << _("bone id =") << (*vecIt)->boneId << _(" loops =") << (*vecIt)->loops << _("\n");
//    }
//    wxMessageBox( test );


}

std::vector<BoneState*>* BoneManager::getBonesStates()
{
    return bonesStates;
}


void BoneManager::mouseDown(wxMouseEvent& event)
{
    // if creating bones mode
    if( projectFrame->modeType() == 1 )
    {
        if( !rootBone )
        {
            creatingBone = TRUE;
            rootBone = new Bone( wxRealPoint( event.GetPosition().x, event.GetPosition().y ), wxRealPoint( event.GetPosition().x, event.GetPosition().y ) );
        }
        else
        {
            if( hovered )
            {
                creatingBone = TRUE;
                selected = new Bone( hovered, hovered->getHoveredJoint() );
            }
        }
    }

    // if rotating and moving bones mode
    if( projectFrame->modeType() == 0 )
    {
        if( hovered )
        {
            if (selected) // unselect previous selection
                selected->selectJoint(Bone::NON);
            selected = hovered;
            selected->selectJoint( hovered->getHoveredJoint() );

            dragging = TRUE;
            skeletonTree->updateSelection();
            updateBoneInfo();

            Refresh();
        }
    }
}

void BoneManager::updateBoneInfo() const
{
    //double loopsAbsolute = selected->getLoops() - selected->getAngleOrginal() / (2*M_PI);
    double loopsRelative = selected->getLoopsRelative();

    projectFrame->setBoneInfo(/*loopsAbsolute*/loopsRelative, selected->getAngleMin(), selected->getAngleMax(), selected->getName(), selected->isMotion(),
            /*sprite parts*/  selected->getSpriteFileName(), selected->getSpritePos() );
}

void BoneManager::rebildSkeletonTree() const
{
    if (skeletonTree)
        skeletonTree->rebuild(rootBone);
}

void BoneManager::mouseReleased(wxMouseEvent& event)
{
    // if creating bones mode
    if( projectFrame->modeType() == 1 )
    {
        if( creatingBone )
        {
            if( rootBone && rootBone->getChildren().empty() )
            {
                projectFrame->getTimeLine()->Refresh();
            }
            animManager->addState(0);
            skeletonTree->rebuild(rootBone);
            creatingBone = FALSE;
        }
    }

    if (dragging)
    {
        //double loopsAbsolute = selected->getLoops() - selected->getAngleOrginal() / (2*M_PI);
        this->projectFrame->setBoneLoops(selected->getLoopsRelative() );
        dragging = FALSE;
    }
}


void BoneManager::saveSkeletonToFile(const wxString& fileName, bool withAnimation)
{
    if(!rootBone)
    {
        std::cerr << "There are no bones" << std::endl;
        return;
    }

    wxXmlDocument xml;
    wxXmlNode *mainRoot = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("bonyfy"), wxT(""));
    xml.SetRoot(mainRoot);

    // SAVE MOVIE
    if (withAnimation)
    {
        wxXmlNode *movieRoot = new wxXmlNode(mainRoot, wxXML_ELEMENT_NODE, wxT("movie"), wxT(""));
        movieRoot->AddProperty( new wxXmlProperty(_("length"), wxString::Format(wxT("%i"), config->getLength())) );
        movieRoot->AddProperty( new wxXmlProperty(_("FPS"), wxString::Format(wxT("%i"), config->getFPS())) );
        movieRoot->AddProperty( new wxXmlProperty(_("width"), wxString::Format(wxT("%i"), config->getCanvasSize().GetWidth())));
        movieRoot->AddProperty( new wxXmlProperty(_("heigth"), wxString::Format(wxT("%i"), config->getCanvasSize().GetHeight())));

        const std::map< unsigned long, std::vector< BoneState*>* > &framesInfo = this->animManager->getFramesInfo();
        std::map< unsigned long, std::vector< BoneState*>* >::const_iterator mapIt;

        // Addnig frames
        for(mapIt = framesInfo.begin(); mapIt != framesInfo.end(); ++mapIt )
        {
            wxXmlNode* frameNode = new wxXmlNode(movieRoot, wxXML_ELEMENT_NODE, wxT("frame"), wxT(""));
            frameNode->AddProperty( new wxXmlProperty(_("number"), wxString::Format(wxT("%i"), (*mapIt).first )) );

            // Addnig bone states
            std::vector< BoneState*>* states = (*mapIt).second;
            std::vector< BoneState*>::iterator bonesIt;
            // rootBone State
            RootState* rootState;
            try
            {
                rootState =  dynamic_cast<RootState*>( (*states)[0] );
            }
             catch (std::bad_cast ex)
            {
                wxMessageBox( wxT("Dynamic cast fail in method BoneManager::saveSkeletonToFile(const wxString& fileName, bool withAnimation)") );
                std::cerr << ex.what() << std::endl;
                return;
            }
            wxXmlNode* rootBoneNode = new wxXmlNode(frameNode, wxXML_ELEMENT_NODE, wxT("rootBone"), wxT(""));
            rootBoneNode->AddProperty ( new wxXmlProperty(_("id"), wxString::Format(wxT("%i"),rootState->boneId)) );
            rootBoneNode->AddProperty ( new wxXmlProperty(_("xTranslation"), wxString::Format(wxT("%lf"),rootState->translation.x)) );
            rootBoneNode->AddProperty ( new wxXmlProperty(_("yTranslation"), wxString::Format(wxT("%lf"),rootState->translation.y)) );
            rootBoneNode->AddProperty ( new wxXmlProperty(_("loops"), wxString::Format(wxT("%lf"),rootState->loops)) );
            rootBoneNode->AddProperty ( new wxXmlProperty(_("motion"), wxString::Format(wxT("%i"),rootState->motion)) );

            //other bones
            bonesIt = states->begin();
            for(++bonesIt; bonesIt != states->
            end(); ++bonesIt)
            {
                BoneState* boneState = (*bonesIt);
                wxXmlNode* boneNode = new wxXmlNode(frameNode, wxXML_ELEMENT_NODE, wxT("bone"), wxT(""));
                boneNode->AddProperty ( new wxXmlProperty(_("id"), wxString::Format(wxT("%i"),boneState->boneId)) );
                boneNode->AddProperty ( new wxXmlProperty(_("loops"), wxString::Format(wxT("%lf"),boneState->loops)) );
                boneNode->AddProperty ( new wxXmlProperty(_("motion"), wxString::Format(wxT("%i"),boneState->motion)) );
            }

        }

    }//END SAVE MOVIE

    // SAVE SKELETON
    wxXmlNode *skeletonRoot = new wxXmlNode(mainRoot, wxXML_ELEMENT_NODE, wxT("skeleton"), wxT(""));
    skeletonRoot->AddProperty(new wxXmlProperty(_("name"), _("szkielecik")));

    //wxXmlProperty* sprite = new (_("sprite"), rootBone->get)
    wxXmlProperty* p_spriteY = new wxXmlProperty(_("spriteY"), wxString::Format(wxT("%i"), rootBone->getSpritePos().y ));
    wxXmlProperty* p_spriteX = new wxXmlProperty(_("spriteX"), wxString::Format(wxT("%i"), rootBone->getSpritePos().x ), p_spriteY);
    wxXmlProperty* p_spriteSrc = new wxXmlProperty(_("spriteSrc"), rootBone->getSpriteFileName(), p_spriteX);
    wxXmlProperty* p_aOrginal = new wxXmlProperty(_("loopsOrginal"), wxString::Format(wxT("%lf"),rootBone->getLoopsOrginal()), p_spriteSrc);
    wxXmlProperty* p_aMax = new wxXmlProperty(_("angleMax"), wxString::Format(wxT("%lf"),rootBone->getAngleMax()), p_aOrginal);
    wxXmlProperty* p_aMin = new wxXmlProperty(_("angleMin"), wxString::Format(wxT("%lf"),rootBone->getAngleMin()), p_aMax);
    wxXmlProperty* p_len = new wxXmlProperty(_("length"), wxString::Format(wxT("%lf"),rootBone->length()), p_aMin);
    wxXmlProperty* p_yPos = new wxXmlProperty(_("yPos"), wxString::Format(wxT("%lf"),rootBone->getBegin()->y), p_len);
    wxXmlProperty* p_xPos = new wxXmlProperty(_("xPos"), wxString::Format(wxT("%lf"),rootBone->getBegin()->x), p_yPos);
    wxXmlProperty* p_name = new wxXmlProperty(_("name"), rootBone->getName(), p_xPos);
    wxXmlProperty* p_id = new wxXmlProperty(_("id"), wxString::Format(wxT("%i"),rootBone->getBoneId()), p_name);
    wxXmlProperty* p_joint;

    wxXmlNode *xRootBone = new wxXmlNode(skeletonRoot, wxXML_ELEMENT_NODE, _("rootBone"), _(""), p_id);

    std::list< wxXmlNode*> nodes;
    nodes.push_back(xRootBone);

    std::list< Bone*> bones;
    bones.push_back(rootBone);
    std::list< Bone* >::iterator listIt, childenIt;
    for ( listIt = bones.begin(); listIt != bones.end(); ++listIt)
    {
        // rootBone properties are already added
        if ( (*listIt) != rootBone )
        {
            p_spriteY = new wxXmlProperty(_("spriteY"), wxString::Format(wxT("%i"), (*listIt)->getSpritePos().y ));
            p_spriteX = new wxXmlProperty(_("spriteX"), wxString::Format(wxT("%i"), (*listIt)->getSpritePos().x ), p_spriteY);
            p_spriteSrc = new wxXmlProperty(_("spriteSrc"), (*listIt)->getSpriteFileName(), p_spriteX);
            p_aOrginal = new wxXmlProperty(_("loopsOrginal"), wxString::Format(wxT("%lf"),(*listIt)->getLoopsOrginal()), p_spriteSrc);
            p_aMax = new wxXmlProperty(_("angleMax"), wxString::Format(wxT("%lf"),(*listIt)->getAngleMax()), p_aOrginal);
            p_aMin = new wxXmlProperty(_("angleMin"), wxString::Format(wxT("%lf"),(*listIt)->getAngleMin()), p_aMax);
            p_len = new wxXmlProperty(_("length"), wxString::Format(wxT("%lf"), (*listIt)->length()), p_aMin);
            p_joint = new wxXmlProperty(_("jointNumber"), wxString::Format(wxT("%i"),(*listIt)->getJointNumber()), p_len);
            p_name = new wxXmlProperty(_("name"), (*listIt)->getName(), p_joint);
            p_id = new wxXmlProperty(_("id"), wxString::Format(wxT("%i"),(*listIt)->getBoneId()), p_name);

            wxXmlNode *xIBone = new wxXmlNode(skeletonRoot, wxXML_ELEMENT_NODE, _("bone"), _(""), p_id);
            nodes.push_back(xIBone);

            // Add paretn id
            p_id = new wxXmlProperty( _("id"), wxString::Format(wxT("%i"), (*listIt)->getParent()->getBoneId()) );
            new wxXmlNode(nodes.back(), wxXML_ELEMENT_NODE, _("parent"), _(""),  p_id);
        }

        // Add Children ids
        for ( childenIt = ( (*listIt)->getChildren() ).begin(); childenIt != ( (*listIt)->getChildren() ).end(); ++childenIt)
            bones.push_back( (*childenIt) );
    }

    xml.Save(fileName);
}


void BoneManager::loadSkeletonFromFile(const wxString& fileName, bool withAnimation)
{
    wxXmlDocument xml (fileName);
    if (!xml.IsOk())
    {
        std::cerr << "wrong file";
        return;
    }

    wxXmlNode *mainRoot = xml.GetRoot();

    if (mainRoot->GetName() != wxT("bonyfy"))
    {
        assert(!"Bad XML file");
    }

    // LOADING BONES
    wxXmlNode *skeletonNode = mainRoot->GetChildren();
    wxXmlNode *tmp;

    if( !(tmp = skeletonNode->GetChildren()) )
    {
        std::cerr << "No bones";
        return;
    }

    // Pushing into map
    std::map <unsigned, wxXmlNode*> nodes;
    std::map <unsigned, unsigned> association;

    double x, y, length, loopsOrginal, aMin, aMax;
    long int id, jointNumber, spriteX, spriteY;

    std::list<wxXmlNode* > listNodes;
    std::list<wxXmlNode*>::iterator listNodeIt;
    listNodes.push_back(tmp);

    for(listNodeIt = listNodes.begin(); listNodeIt != listNodes.end(); ++listNodeIt)
    {
        if ( (*listNodeIt)->GetNext()  )
            listNodes.push_back((*listNodeIt)->GetNext());

        if( ! (*listNodeIt)->GetPropVal(_("id"), _("0")).ToLong(&id) )
            {  wxMessageBox(_("Fail in recreating skeleton from file, wrong data - error in parsing toDouble")); return;}

        nodes.insert( std::pair<long, wxXmlNode*> (id, (*listNodeIt)) );
    }

    // Recreating bones
    // Recrrating rootBone
    wxXmlNode *rBoneNode = nodes[0];
    if(   ! rBoneNode->GetPropVal(_("id"), _("0")).ToLong(&id)
       || ! rBoneNode->GetPropVal(_("xPos"), _("20")).ToDouble(&x)
       || ! rBoneNode->GetPropVal(_("yPos"), _("20")).ToDouble(&y)
       || ! rBoneNode->GetPropVal(_("length"), _("20")).ToDouble(&length)
       || ! rBoneNode->GetPropVal(_("loopsOrginal"), _("0")).ToDouble(&loopsOrginal)
       || ! rBoneNode->GetPropVal(_("angleMin"), _("0")).ToDouble(&aMin)
       || ! rBoneNode->GetPropVal(_("angleMax"), _("0")).ToDouble(&aMax)
       || ! rBoneNode->GetPropVal(_("spriteX"), _("0")).ToLong(&spriteX)
       || ! rBoneNode->GetPropVal(_("spriteY"), _("0")).ToLong(&spriteY)
       ) { wxMessageBox(_("Fail in recreating skeleton from file, wrong data - error in parsing toDouble")); return; }

    loopsOrginal = -loopsOrginal;
    this->rootBone = new Bone( wxRealPoint(x, y), wxRealPoint( x + length*cos(loopsOrginal*2*M_PI), y + length*sin(loopsOrginal*2*M_PI) ), rBoneNode->GetPropVal(_("name"), _("DefaultValue")) );
    this->rootBone->setAngleMinMax( aMin, aMax );

    wxString spriteSrc = rBoneNode->GetPropVal(_("spriteSrc"), _(""));
    if (!spriteSrc.empty ())
    {
        wxImage sprite;
        if (sprite.LoadFile(spriteSrc) )
        {
            this->rootBone->setSpritePos(wxPoint(spriteX, spriteY));
            this->rootBone->setSpriteFileName(spriteSrc);
            this->rootBone->setSprite( sprite );
        }
    }

    association.insert( std::pair<unsigned, unsigned>(0,0) );

    // Recreating other bones
    std::map <unsigned, wxXmlNode*>::iterator mapIt;
    for(mapIt = nodes.begin(); mapIt != nodes.end(); ++mapIt)
    {
        if ( (*mapIt).first == 0 ) // rootBone already done
            continue;

        tmp = (*mapIt).second;

        // searching for parent
        wxXmlNode* next = tmp->GetChildren();

        long idParent;
        if( ! next->GetPropVal(_("id"), _("-1")).ToLong(&idParent) )
            {  wxMessageBox(_("Fail in recreating skeleton from file, wrong data - error in parsing toDouble")); return;}

        // getting bones properties
        if(    ! tmp->GetPropVal(_("id"), _("-1")).ToLong(&id)
            || ! tmp->GetPropVal(_("jointNumber"), _("1")).ToLong(&jointNumber)
            || ! tmp->GetPropVal(_("length"), _("20")).ToDouble(&length)
            || ! tmp->GetPropVal(_("loopsOrginal"), _("0")).ToDouble(&loopsOrginal)
            || ! tmp->GetPropVal(_("angleMin"), _("0")).ToDouble(&aMin)
            || ! tmp->GetPropVal(_("angleMax"), _("0")).ToDouble(&aMax)
            || ! tmp->GetPropVal(_("spriteX"), _("0")).ToLong(&spriteX)
            || ! tmp->GetPropVal(_("spriteY"), _("0")).ToLong(&spriteY) )
        { wxMessageBox(_("Fail in recreating skeleton from file, wrong data - error in parsing toDouble")); return; }

        Bone* parent = this->findBoneById ( association[idParent] );
        if (!parent)
             wxMessageBox(_("no parent for bone in loading skeleton from file"));
        Bone* bone = new Bone(parent, jointNumber, tmp->GetPropVal(_("name"), _("DefaultValue")), aMin, aMax);
        loopsOrginal = -loopsOrginal;
        bone->setEnd( wxRealPoint(bone->getBegin()->x + length*cos(loopsOrginal*2*M_PI), bone->getBegin()->y + length*sin(loopsOrginal*2*M_PI)) );

        wxString spriteSrc = tmp->GetPropVal(_("spriteSrc"), _(""));
        if (!spriteSrc.empty ())
        {
            wxImage sprite;
            if (sprite.LoadFile(spriteSrc) )
            {
                bone->setSpritePos(wxPoint(spriteX, spriteY));
                bone->setSpriteFileName(spriteSrc);
                bone->setSprite( sprite );
            }
        }

        association.insert( std::pair<unsigned, unsigned>(id, bone->getBoneId()) );
    }

    saveSkeletonState(true); ////////////////////////////////////// do spawdzeniea
    rebildSkeletonTree();

    this->selected = rootBone;
    this->selected->selectJoint(Bone::BEGIN);


    // LOADING MOVIE
    if (withAnimation)
    {
        wxXmlNode *movieNode = skeletonNode->GetNext();

        long length, FPS, width, height;

        if(    ! movieNode->GetPropVal(_("length"), _("0")).ToLong(&length)
            || ! movieNode->GetPropVal(_("FPS"), _("10")).ToLong(&FPS)
            || ! movieNode->GetPropVal(_("width"), _("100")).ToLong(&width)
            || ! movieNode->GetPropVal(_("height"), _("100")).ToLong(&height) )
        { wxMessageBox(_("Fail in recreating skeleton from file, wrong data - error in parsing ToLong")); return; }

        this->config->setCanvasSize(width, height);
        this->config->setLength(length);
        this->config->setFPS(FPS);

        wxXmlNode *frameNode;
        if( !(frameNode = movieNode->GetChildren()) )
        {
            std::cerr << "No frames";
            return;
        }

        double xTranslation, yTranslation, loops;
        long id, motion;

        // Reading frames
        do{
            // Reading bone states
            std::vector<BoneState* > *states = new std::vector<BoneState*>();
            std::list<wxXmlNode*> nodes;
            std::list<wxXmlNode*>::reverse_iterator nodesIt;

            tmp = frameNode->GetChildren();
            do{ // for sure there are bones, at least rootbone
                nodes.push_back(tmp);
            }while ( (tmp = tmp->GetNext()) );

            nodesIt = nodes.rbegin(); // RootState in here
            tmp = (*nodesIt);

            // getting rootbone state properties
            if(    ! tmp->GetPropVal(_("id"), _("-1")).ToLong(&id)
                || ! tmp->GetPropVal(_("xTranslation"), _("20")).ToDouble(&xTranslation)
                || ! tmp->GetPropVal(_("yTranslation"), _("0")).ToDouble(&yTranslation)
                || ! tmp->GetPropVal(_("loops"), _("0")).ToDouble(&loops)
                || ! tmp->GetPropVal(_("motion"), _("0")).ToLong(&motion) )
            { wxMessageBox(_("Fail in recreating skeleton from file, wrong data - error in parsing toDouble")); return; }

            states->push_back( new RootState(id, loops, motion, wxRealPoint(xTranslation, yTranslation)) );

            // gettin others bone state properties
            for (++nodesIt; nodesIt != nodes.rend(); ++nodesIt)
            {
                tmp = (*nodesIt);
                if(    ! tmp->GetPropVal(_("id"), _("-1")).ToLong(&id)
                    || ! tmp->GetPropVal(_("loops"), _("0")).ToDouble(&loops)
                    || ! tmp->GetPropVal(_("motion"), _("0")).ToLong(&motion))
                { wxMessageBox(_("Fail in recreating skeleton from file, wrong data - error in parsing toDouble")); return; }

                states->push_back( new BoneState(id, loops, motion) );
            }

            long number;
            if(! frameNode->GetPropVal(_("number"), _("-1")).ToLong(&number) )
                { wxMessageBox(_("Fail in recreating skeleton from file, wrong data - error in parsing toDouble")); return; }

            this->animManager->addState(number, states);

        }while ( (frameNode = frameNode->GetNext()) );

        // Apply first frame
        applySkeletonState(0);
    } // END LOADING MOVIES

    Refresh();
}

ProjectFrame* BoneManager::getProjectFrame() const
{
    return projectFrame;
}
